home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / tar_1_11 / rmt.c < prev    next >
C/C++ Source or Header  |  1994-01-23  |  6KB  |  282 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. /*
  25.  * rmt
  26.  */
  27. #include <stdio.h>
  28. #include <sgtty.h>
  29. #include <sys/types.h>
  30. #include <sys/socket.h>
  31. #ifdef HAVE_SYS_GENTAPE_H    /* e.g., ISC UNIX */
  32. #include <sys/gentape.h>
  33. #else
  34. #include <sys/mtio.h>
  35. #endif
  36. #include <errno.h>
  37.  
  38. #if defined (_I386) && defined (_AIX)
  39. #include <fcntl.h>
  40. #endif
  41.  
  42. #ifdef HAVE_UNISTD_H
  43. #include <unistd.h>
  44. #else
  45. long lseek ();
  46. #endif
  47.  
  48. #ifdef STDC_HEADERS
  49. #include <string.h>
  50. #include <stdlib.h>
  51. #else
  52. extern char *malloc ();
  53. #endif
  54.  
  55. int tape = -1;
  56.  
  57. char *record;
  58. int maxrecsize = -1;
  59. char *checkbuf ();
  60. void getstring ();
  61. void error ();
  62.  
  63. #define    SSIZE    64
  64. char device[SSIZE];
  65. char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
  66.  
  67. extern errno;
  68. extern char *sys_errlist[];
  69. char resp[BUFSIZ];
  70.  
  71. FILE *debug;
  72. #define    DEBUG(f)    if (debug) fprintf(debug, f)
  73. #define    DEBUG1(f,a)    if (debug) fprintf(debug, f, a)
  74. #define    DEBUG2(f,a1,a2)    if (debug) fprintf(debug, f, a1, a2)
  75.  
  76. int
  77. main (argc, argv)
  78.      int argc;
  79.      char **argv;
  80. {
  81.   int rval;
  82.   char c;
  83.   int n, i, cc;
  84.  
  85.   argc--, argv++;
  86.   if (argc > 0)
  87.     {
  88.       debug = fopen (*argv, "w");
  89.       if (debug == 0)
  90.     exit (1);
  91.       (void) setbuf (debug, (char *) 0);
  92.     }
  93. top:
  94.   errno = 0;
  95.   rval = 0;
  96.   if (read (0, &c, 1) != 1)
  97.     exit (0);
  98.   switch (c)
  99.     {
  100.  
  101.     case 'O':
  102.       if (tape >= 0)
  103.     (void) close (tape);
  104.       getstring (device);
  105.       getstring (mode);
  106.       DEBUG2 ("rmtd: O %s %s\n", device, mode);
  107. #if defined (i386) && defined (AIX)
  108.       /* This is alleged to fix a byte ordering problem. */
  109.       /* I'm quite suspicious if it's right. -- mib */
  110.       {
  111.     int oflag = atoi (mode);
  112.     int nflag = 0;
  113.     if ((oflag & 3) == 0)
  114.       nflag |= O_RDONLY;
  115.     if (oflag & 1)
  116.       nflag |= O_WRONLY;
  117.     if (oflag & 2)
  118.       nflag |= O_RDWR;
  119.     if (oflag & 0x0008)
  120.       nflag |= O_APPEND;
  121.     if (oflag & 0x0200)
  122.       nflag |= O_CREAT;
  123.     if (oflag & 0x0400)
  124.       nflag |= O_TRUNC;
  125.     if (oflag & 0x0800)
  126.       nflag |= O_EXCL;
  127.     tape = open (device, nflag, 0666);
  128.       }
  129. #else
  130.       tape = open (device, atoi (mode), 0666);
  131. #endif
  132.       if (tape < 0)
  133.     goto ioerror;
  134.       goto respond;
  135.  
  136.     case 'C':
  137.       DEBUG ("rmtd: C\n");
  138.       getstring (device);    /* discard */
  139.       if (close (tape) < 0)
  140.     goto ioerror;
  141.       tape = -1;
  142.       goto respond;
  143.  
  144.     case 'L':
  145.       getstring (count);
  146.       getstring (pos);
  147.       DEBUG2 ("rmtd: L %s %s\n", count, pos);
  148.       rval = lseek (tape, (long) atoi (count), atoi (pos));
  149.       if (rval < 0)
  150.     goto ioerror;
  151.       goto respond;
  152.  
  153.     case 'W':
  154.       getstring (count);
  155.       n = atoi (count);
  156.       DEBUG1 ("rmtd: W %s\n", count);
  157.       record = checkbuf (record, n);
  158.       for (i = 0; i < n; i += cc)
  159.     {
  160.       cc = read (0, &record[i], n - i);
  161.       if (cc <= 0)
  162.         {
  163.           DEBUG ("rmtd: premature eof\n");
  164.           exit (2);
  165.         }
  166.     }
  167.       rval = write (tape, record, n);
  168.       if (rval < 0)
  169.     goto ioerror;
  170.       goto respond;
  171.  
  172.     case 'R':
  173.       getstring (count);
  174.       DEBUG1 ("rmtd: R %s\n", count);
  175.       n = atoi (count);
  176.       record = checkbuf (record, n);
  177.       rval = read (tape, record, n);
  178.       if (rval < 0)
  179.     goto ioerror;
  180.       (void) sprintf (resp, "A%d\n", rval);
  181.       (void) write (1, resp, strlen (resp));
  182.       (void) write (1, record, rval);
  183.       goto top;
  184.  
  185.     case 'I':
  186.       getstring (op);
  187.       getstring (count);
  188.       DEBUG2 ("rmtd: I %s %s\n", op, count);
  189. #ifdef MTIOCTOP
  190.       {
  191.     struct mtop mtop;
  192.     mtop.mt_op = atoi (op);
  193.     mtop.mt_count = atoi (count);
  194.     if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0)
  195.       goto ioerror;
  196.     rval = mtop.mt_count;
  197.       }
  198. #endif
  199.       goto respond;
  200.  
  201.     case 'S':            /* status */
  202.       DEBUG ("rmtd: S\n");
  203.       {
  204. #ifdef MTIOCGET
  205.     struct mtget mtget;
  206.     if (ioctl (tape, MTIOCGET, (char *) &mtget) < 0)
  207.       goto ioerror;
  208.     rval = sizeof (mtget);
  209.     (void) sprintf (resp, "A%d\n", rval);
  210.     (void) write (1, resp, strlen (resp));
  211.     (void) write (1, (char *) &mtget, sizeof (mtget));
  212. #endif
  213.     goto top;
  214.       }
  215.  
  216.     default:
  217.       DEBUG1 ("rmtd: garbage command %c\n", c);
  218.       exit (3);
  219.     }
  220. respond:
  221.   DEBUG1 ("rmtd: A %d\n", rval);
  222.   (void) sprintf (resp, "A%d\n", rval);
  223.   (void) write (1, resp, strlen (resp));
  224.   goto top;
  225. ioerror:
  226.   error (errno);
  227.   goto top;
  228. }
  229.  
  230. void
  231. getstring (bp)
  232.      char *bp;
  233. {
  234.   int i;
  235.   char *cp = bp;
  236.  
  237.   for (i = 0; i < SSIZE; i++)
  238.     {
  239.       if (read (0, cp + i, 1) != 1)
  240.     exit (0);
  241.       if (cp[i] == '\n')
  242.     break;
  243.     }
  244.   cp[i] = '\0';
  245. }
  246.  
  247. char *
  248. checkbuf (record, size)
  249.      char *record;
  250.      int size;
  251. {
  252.   if (size <= maxrecsize)
  253.     return (record);
  254.   if (record != 0)
  255.     free (record);
  256.   record = malloc (size);
  257.   if (record == 0)
  258.     {
  259.       DEBUG ("rmtd: cannot allocate buffer space\n");
  260.       exit (4);
  261.     }
  262.   maxrecsize = size;
  263. #ifdef SO_RCVBUF
  264.   while (size > 1024 &&
  265.    setsockopt (0, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof (size)) < 0)
  266.     size -= 1024;
  267. #else
  268.   size = 1 + ((size - 1) % 1024);
  269. #endif
  270.   return (record);
  271. }
  272.  
  273. void
  274. error (num)
  275.      int num;
  276. {
  277.  
  278.   DEBUG2 ("rmtd: E %d (%s)\n", num, sys_errlist[num]);
  279.   (void) sprintf (resp, "E%d\n%s\n", num, sys_errlist[num]);
  280.   (void) write (1, resp, strlen (resp));
  281. }
  282.